{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center><img src=\"../image/CLBLOGO.jpg\" alt=\"创乐博\" style=\"width: 300px;\"/></center>\n",
    "\n",
    "# 8.机器人球体追踪\n",
    "\n",
    "@－－－－湖南创乐博智能科技有限公司－－－－<br>\n",
    "@  文件名：8.机器人球体追踪.ipynb <br>\n",
    "@  版本：V2.0 <br>\n",
    "@  author: zhulin<br>\n",
    "@  说明：机器人球体追踪<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "from LOBOROBOT import LOBOROBOT # 载入机器人库\n",
    "import  RPi.GPIO as GPIO\n",
    "import time  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "kernel = np.ones((5,5),np.uint8)\n",
    "# 按键及LED初始化\n",
    "BtnPin  = 19\n",
    "Gpin    = 5\n",
    "Rpin    = 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "clbrobot = LOBOROBOT()  # 实例化机器人对象\n",
    "\n",
    "# Configure min and max servo pulse lengths\n",
    "servo_min = 150  # Min pulse length out of 4096\n",
    "servo_max = 600  # Max pulse length out of 4096\n",
    "\n",
    "# 频率设置为50hz，适用于舵机系统。\n",
    "clbrobot.set_servo_angle(10,90)  # 底座舵机 90 \n",
    "clbrobot.set_servo_angle(9,30)  # 顶部舵机 30\n",
    "time.sleep(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 打开摄像头"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cam = cv2.VideoCapture(0,cv2.CAP_V4L2)\n",
    "cam.set(3,320)\n",
    "cam.set(4,240)\n",
    "cam.isOpened()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "17e50797dfcb4738aee595de2ba7546e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Image(value=b'', format='jpeg', height='240', width='320'), Image(value=b'', format='jpeg', hei…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import traitlets\n",
    "import ipywidgets.widgets as widgets\n",
    "from IPython.display import display\n",
    "\n",
    "def bgr8_to_jpeg(value, quality=75):\n",
    "    return bytes(cv2.imencode('.jpg', value)[1])\n",
    "\n",
    "FGmaskComp_img = widgets.Image(format='jpeg', width=320, height=240)\n",
    "frame_img = widgets.Image(format='jpeg', width=320, height=240)\n",
    "\n",
    "dispaly_img = widgets.HBox([FGmaskComp_img,frame_img])\n",
    "display(dispaly_img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 线程函数操作库\n",
    "import threading # 线程\n",
    "import ctypes\n",
    "import inspect\n",
    "\n",
    "# 线程结束代码\n",
    "def _async_raise(tid, exctype):\n",
    "    tid = ctypes.c_long(tid)\n",
    "    if not inspect.isclass(exctype):\n",
    "        exctype = type(exctype)\n",
    "    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
    "    if res == 0:\n",
    "        raise ValueError(\"invalid thread id\")\n",
    "    elif res != 1:\n",
    "        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
    "        raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
    "        \n",
    "def stop_thread(thread):\n",
    "    _async_raise(thread.ident, SystemExit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4f3e9925d4c24373b684900101298988",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(HBox(children=(IntSlider(value=20, description='hueLower：', max=179, min=12), IntSlider(value=3…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "hueLower = widgets.IntSlider(min=12,max=179,step=1,description='hueLower：',value=20)\n",
    "hueUpper = widgets.IntSlider(min=30,max=179,step=1,description='hueUpper：',value=30)\n",
    "\n",
    "satLow = widgets.IntSlider(min=50,max=255,step=1,description='satLow：',value=50)\n",
    "satHigh = widgets.IntSlider(min=255,max=255,step=1,description='satHigh：',value=255)\n",
    "\n",
    "valLow = widgets.IntSlider(min=50,max=255,step=1,description='valLow：',value=50)\n",
    "valHigh = widgets.IntSlider(min=255,max=255,step=1,description='valHigh：',value=255)\n",
    "\n",
    "slider_img=widgets.VBox([\n",
    "              widgets.HBox([hueLower,hueUpper]),\n",
    "              widgets.HBox([satLow,satHigh]),\n",
    "              widgets.HBox([valLow,valHigh])\n",
    "             ])\n",
    "display(slider_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 按键处理函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def keysacn():\n",
    "    val = GPIO.input(BtnPin)\n",
    "    while GPIO.input(BtnPin) == False:\n",
    "        val = GPIO.input(BtnPin)\n",
    "    while GPIO.input(BtnPin) == True:\n",
    "        time.sleep(0.01)\n",
    "        val = GPIO.input(BtnPin)\n",
    "        if val == True:\n",
    "            GPIO.output(Rpin,1)\n",
    "            while GPIO.input(BtnPin) == False:\n",
    "                GPIO.output(Rpin,0)\n",
    "        else:\n",
    "            GPIO.output(Rpin,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "GPIO.setwarnings(False) \n",
    "GPIO.setmode(GPIO.BCM)\n",
    "GPIO.setup(Gpin, GPIO.OUT)     # 设置绿色Led引脚模式输出\n",
    "GPIO.setup(Rpin, GPIO.OUT)     # 设置红色Led引脚模式输出\n",
    "GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    # 设置输入BtnPin模式，拉高至高电平(3.3V) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "def Video_display():\n",
    "    # 键盘控制函数 \n",
    "    keysacn()\n",
    "    while(1):\n",
    "        buzz = 0\n",
    "        _, frame = cam.read()\n",
    "        frame=cv2.flip(frame, 1) \n",
    "        \n",
    "        # 转换到HSV\n",
    "        hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)\n",
    "        hue,sat,val = cv2.split(hsv)\n",
    "        \n",
    "        hueLow=hueLower.value\n",
    "        hueUp=hueUpper.value\n",
    "    \n",
    "        Ls= satLow.value\n",
    "        Us = satHigh.value\n",
    "    \n",
    "        Lv=valLow.value\n",
    "        Uv=valHigh.value\n",
    "    \n",
    "        l_b=np.array([hueLow,Ls,Lv])\n",
    "        u_b=np.array([hueUp,Us,Uv])\n",
    "    \n",
    "    \n",
    "        FGmaskComp=cv2.inRange(hsv,l_b,u_b)\n",
    "        FGmaskComp_img.value = bgr8_to_jpeg(FGmaskComp)\n",
    "        \n",
    "        # 应用阈值\n",
    "        hthresh = cv2.inRange(np.array(hue),np.array(hueLow),np.array(hueUp))\n",
    "        sthresh = cv2.inRange(np.array(sat),np.array(Ls),np.array(Us))\n",
    "        vthresh = cv2.inRange(np.array(val),np.array(Lv),np.array(Uv))\n",
    "    \n",
    "        # h s和v\n",
    "        tracking = cv2.bitwise_and(hthresh,cv2.bitwise_and(sthresh,vthresh))\n",
    "    \n",
    "        # 一些morpholigical过滤\n",
    "        dilation = cv2.dilate(tracking,kernel,iterations = 1)\n",
    "        closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)\n",
    "        closing = cv2.GaussianBlur(closing,(5,5),0)\n",
    "    \n",
    "        # 使用HoughCircles检测圆\n",
    "        circles = cv2.HoughCircles(closing,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=50,minRadius=10,maxRadius=0)\n",
    "        # circles = np.uint16(np.around(circles))\n",
    "        clbrobot.t_stop(0)\n",
    "    \n",
    "        # 画圆圈\n",
    "        if circles is not None:\n",
    "            x, y, r = circles[0][0]\n",
    "            x_p = int(round(x))\n",
    "            print(x_p)\n",
    "            for i in circles[0,:]:\n",
    "                    # 如果球很远，用绿色画出来\n",
    "                    if int(round(i[2])) < 30:\n",
    "                            cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,255,0),5)\n",
    "                            cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,255,0),10)\n",
    "                    # 或者用红色画\n",
    "                    elif int(round(i[2])) > 35:\n",
    "                            cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,0,255),5)\n",
    "                            cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,0,255),10)\n",
    "                            buzz = 1  \n",
    "            # 设定一个范围\n",
    "            x_Lower = 150\n",
    "            x_Upper = 180\n",
    "            # 判断X方向范围来判断机器人的运动\n",
    "            if x_p > x_Lower and x_p < x_Upper:\n",
    "                    clbrobot.t_up(30,0)\n",
    "            elif x_p < x_Lower:\n",
    "                clbrobot.turnLeft(20,0)              \n",
    "            elif x_p > x_Upper:\n",
    "                clbrobot.turnRight(20,0)    \n",
    "            else:\n",
    "                clbrobot.t_stop(0)\n",
    "        # 在帧中显示结果\n",
    "        frame_img.value = bgr8_to_jpeg(frame)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "155\n",
      "69\n",
      "119\n",
      "117\n",
      "143\n",
      "157\n",
      "235\n",
      "201\n",
      "121\n",
      "53\n",
      "139\n",
      "37\n",
      "15\n",
      "223\n",
      "217\n",
      "201\n",
      "105\n",
      "179\n",
      "277\n",
      "231\n",
      "57\n",
      "135\n",
      "89\n",
      "83\n",
      "49\n",
      "319\n",
      "319\n",
      "203\n",
      "189\n",
      "187\n",
      "191\n",
      "189\n",
      "189\n",
      "191\n",
      "183\n",
      "167\n",
      "145\n",
      "123\n",
      "115\n",
      "91\n",
      "63\n",
      "41\n",
      "49\n",
      "67\n",
      "97\n",
      "119\n",
      "137\n",
      "149\n",
      "145\n",
      "163\n",
      "187\n",
      "213\n",
      "237\n",
      "255\n",
      "269\n",
      "243\n",
      "221\n",
      "197\n",
      "199\n",
      "197\n",
      "201\n",
      "191\n",
      "187\n",
      "173\n",
      "145\n",
      "115\n",
      "87\n",
      "75\n",
      "291\n",
      "197\n",
      "163\n",
      "155\n",
      "123\n",
      "249\n",
      "271\n",
      "167\n",
      "181\n",
      "265\n",
      "263\n",
      "209\n",
      "143\n",
      "133\n",
      "133\n",
      "169\n",
      "173\n",
      "171\n",
      "169\n",
      "177\n",
      "175\n",
      "173\n",
      "179\n",
      "187\n",
      "181\n",
      "183\n",
      "175\n",
      "159\n",
      "159\n",
      "259\n",
      "209\n",
      "213\n",
      "215\n",
      "223\n",
      "233\n",
      "225\n",
      "227\n",
      "207\n",
      "183\n",
      "169\n",
      "141\n",
      "113\n",
      "99\n",
      "87\n",
      "65\n",
      "51\n",
      "21\n",
      "35\n",
      "51\n",
      "67\n",
      "97\n",
      "109\n",
      "123\n",
      "151\n",
      "175\n",
      "203\n",
      "215\n",
      "233\n",
      "257\n",
      "241\n",
      "219\n",
      "193\n",
      "187\n",
      "193\n",
      "195\n",
      "201\n",
      "179\n",
      "145\n",
      "135\n",
      "123\n",
      "89\n",
      "63\n",
      "95\n",
      "111\n",
      "97\n",
      "105\n",
      "101\n",
      "115\n",
      "135\n",
      "223\n",
      "227\n",
      "241\n",
      "245\n",
      "249\n",
      "235\n",
      "213\n",
      "157\n",
      "151\n",
      "175\n",
      "179\n",
      "183\n",
      "189\n",
      "189\n",
      "193\n",
      "195\n",
      "177\n",
      "171\n",
      "151\n",
      "133\n",
      "121\n",
      "77\n",
      "3\n",
      "49\n",
      "49\n",
      "75\n",
      "63\n",
      "117\n",
      "137\n",
      "121\n",
      "117\n",
      "45\n",
      "99\n",
      "131\n",
      "161\n",
      "219\n",
      "221\n",
      "221\n",
      "239\n",
      "237\n",
      "221\n",
      "213\n",
      "181\n",
      "175\n",
      "167\n",
      "165\n",
      "151\n",
      "137\n",
      "107\n",
      "95\n",
      "63\n",
      "41\n",
      "39\n",
      "23\n",
      "31\n",
      "53\n",
      "67\n",
      "79\n",
      "101\n",
      "107\n",
      "115\n",
      "127\n",
      "147\n",
      "173\n",
      "199\n",
      "223\n",
      "239\n",
      "269\n",
      "295\n",
      "259\n",
      "243\n",
      "213\n",
      "227\n",
      "233\n",
      "227\n",
      "235\n",
      "209\n",
      "201\n",
      "171\n",
      "143\n",
      "113\n",
      "107\n",
      "81\n",
      "219\n",
      "257\n",
      "221\n",
      "207\n",
      "209\n",
      "213\n",
      "213\n",
      "217\n",
      "219\n",
      "203\n",
      "185\n",
      "165\n",
      "135\n",
      "115\n",
      "97\n",
      "75\n",
      "51\n",
      "39\n",
      "49\n",
      "69\n",
      "83\n",
      "109\n",
      "121\n",
      "143\n",
      "153\n",
      "167\n",
      "191\n",
      "213\n",
      "239\n",
      "261\n",
      "267\n",
      "275\n",
      "255\n",
      "183\n",
      "181\n",
      "125\n",
      "109\n",
      "91\n",
      "93\n",
      "121\n",
      "145\n",
      "237\n",
      "239\n",
      "229\n",
      "235\n",
      "219\n",
      "215\n",
      "205\n",
      "197\n",
      "197\n",
      "171\n",
      "151\n",
      "121\n",
      "95\n",
      "77\n",
      "55\n",
      "33\n",
      "45\n",
      "47\n",
      "73\n",
      "79\n",
      "97\n",
      "97\n",
      "97\n",
      "183\n",
      "85\n",
      "91\n",
      "127\n",
      "11\n",
      "165\n",
      "127\n",
      "95\n",
      "91\n",
      "67\n",
      "111\n",
      "137\n",
      "153\n",
      "201\n",
      "237\n",
      "211\n",
      "161\n",
      "169\n",
      "163\n",
      "169\n",
      "171\n",
      "169\n",
      "167\n",
      "155\n",
      "161\n",
      "151\n",
      "151\n",
      "169\n",
      "163\n",
      "183\n",
      "195\n",
      "207\n",
      "209\n",
      "233\n",
      "237\n",
      "247\n",
      "241\n",
      "215\n",
      "191\n",
      "183\n",
      "157\n",
      "85\n",
      "61\n",
      "45\n",
      "59\n",
      "79\n",
      "107\n",
      "145\n",
      "147\n",
      "141\n",
      "153\n",
      "165\n",
      "171\n",
      "143\n",
      "127\n",
      "149\n",
      "131\n",
      "117\n",
      "159\n",
      "205\n",
      "239\n",
      "263\n",
      "263\n",
      "227\n",
      "221\n",
      "217\n",
      "203\n",
      "219\n",
      "217\n",
      "193\n",
      "193\n",
      "167\n",
      "151\n",
      "143\n",
      "133\n",
      "141\n",
      "133\n",
      "111\n",
      "121\n",
      "145\n",
      "187\n",
      "229\n",
      "219\n",
      "217\n",
      "139\n",
      "141\n",
      "161\n",
      "157\n",
      "135\n",
      "137\n",
      "141\n",
      "183\n",
      "163\n",
      "197\n",
      "235\n",
      "215\n",
      "161\n",
      "143\n",
      "135\n",
      "171\n",
      "185\n",
      "211\n",
      "241\n",
      "247\n",
      "235\n",
      "225\n",
      "203\n",
      "193\n",
      "189\n",
      "193\n",
      "189\n",
      "179\n",
      "169\n",
      "163\n",
      "153\n",
      "131\n",
      "95\n",
      "81\n",
      "47\n",
      "55\n",
      "41\n",
      "49\n",
      "97\n",
      "147\n",
      "179\n",
      "235\n",
      "233\n",
      "213\n",
      "213\n",
      "209\n",
      "213\n",
      "181\n",
      "171\n",
      "109\n",
      "47\n",
      "43\n",
      "29\n",
      "25\n",
      "65\n",
      "61\n",
      "71\n",
      "97\n",
      "121\n",
      "145\n",
      "157\n",
      "163\n",
      "163\n",
      "155\n",
      "151\n",
      "149\n",
      "129\n",
      "117\n",
      "101\n",
      "123\n",
      "167\n",
      "201\n",
      "181\n",
      "199\n",
      "191\n",
      "181\n",
      "153\n",
      "131\n",
      "121\n",
      "315\n",
      "317\n",
      "47\n",
      "65\n",
      "93\n",
      "131\n",
      "133\n",
      "141\n",
      "97\n",
      "103\n",
      "121\n",
      "175\n",
      "235\n",
      "251\n",
      "227\n",
      "213\n",
      "187\n",
      "53\n",
      "197\n",
      "201\n",
      "181\n",
      "183\n",
      "167\n",
      "161\n",
      "149\n",
      "139\n",
      "117\n",
      "117\n",
      "125\n",
      "121\n",
      "163\n",
      "199\n",
      "205\n",
      "189\n",
      "157\n",
      "131\n",
      "115\n",
      "109\n",
      "103\n",
      "101\n",
      "97\n",
      "155\n",
      "151\n",
      "161\n",
      "147\n",
      "165\n",
      "175\n",
      "207\n",
      "235\n",
      "239\n",
      "257\n",
      "249\n",
      "217\n",
      "175\n",
      "161\n",
      "161\n",
      "171\n",
      "159\n",
      "149\n",
      "155\n",
      "161\n",
      "173\n",
      "167\n",
      "165\n",
      "167\n",
      "207\n",
      "215\n",
      "215\n",
      "221\n",
      "205\n",
      "209\n",
      "195\n",
      "177\n",
      "151\n",
      "115\n",
      "63\n",
      "3\n",
      "51\n",
      "51\n",
      "53\n",
      "59\n",
      "59\n",
      "59\n",
      "69\n",
      "65\n",
      "59\n",
      "61\n",
      "63\n",
      "51\n",
      "81\n",
      "97\n",
      "101\n",
      "117\n",
      "131\n",
      "167\n",
      "269\n",
      "275\n",
      "271\n",
      "269\n",
      "265\n",
      "131\n",
      "141\n",
      "149\n",
      "127\n",
      "147\n",
      "135\n",
      "135\n",
      "149\n",
      "149\n",
      "199\n",
      "197\n",
      "225\n",
      "133\n",
      "121\n",
      "137\n",
      "141\n",
      "151\n",
      "203\n",
      "209\n",
      "219\n",
      "209\n",
      "217\n",
      "221\n",
      "207\n",
      "175\n",
      "151\n",
      "129\n",
      "299\n",
      "105\n",
      "57\n",
      "89\n",
      "125\n",
      "121\n",
      "145\n",
      "161\n",
      "183\n",
      "227\n",
      "187\n",
      "187\n",
      "201\n",
      "163\n",
      "161\n",
      "159\n",
      "157\n",
      "165\n",
      "155\n",
      "163\n",
      "147\n",
      "165\n",
      "165\n",
      "169\n",
      "185\n",
      "195\n",
      "193\n",
      "189\n",
      "179\n",
      "187\n",
      "173\n",
      "165\n",
      "129\n",
      "117\n",
      "117\n",
      "183\n",
      "165\n",
      "163\n",
      "173\n",
      "175\n",
      "187\n",
      "183\n",
      "121\n",
      "123\n",
      "105\n",
      "117\n",
      "121\n",
      "143\n",
      "139\n",
      "151\n",
      "155\n",
      "157\n",
      "153\n",
      "185\n",
      "199\n",
      "219\n",
      "203\n",
      "183\n",
      "199\n",
      "177\n",
      "159\n",
      "147\n",
      "119\n",
      "67\n",
      "79\n",
      "87\n",
      "77\n",
      "67\n",
      "63\n",
      "89\n",
      "105\n",
      "135\n",
      "125\n",
      "117\n",
      "135\n",
      "159\n",
      "175\n",
      "183\n",
      "251\n",
      "271\n",
      "259\n",
      "225\n",
      "181\n",
      "169\n",
      "195\n",
      "201\n",
      "201\n",
      "203\n",
      "203\n",
      "207\n",
      "203\n",
      "191\n",
      "179\n",
      "145\n",
      "111\n",
      "135\n",
      "147\n",
      "135\n",
      "143\n",
      "135\n",
      "133\n",
      "159\n",
      "167\n",
      "181\n",
      "175\n",
      "201\n",
      "133\n",
      "135\n",
      "107\n",
      "131\n",
      "161\n",
      "161\n",
      "189\n",
      "179\n",
      "105\n",
      "105\n",
      "93\n",
      "85\n",
      "117\n",
      "205\n",
      "275\n",
      "285\n",
      "261\n",
      "289\n",
      "283\n",
      "259\n",
      "261\n",
      "259\n",
      "267\n",
      "273\n",
      "269\n",
      "255\n",
      "257\n",
      "247\n",
      "185\n",
      "131\n",
      "183\n",
      "161\n",
      "175\n",
      "179\n",
      "185\n",
      "195\n",
      "207\n",
      "225\n",
      "181\n",
      "173\n",
      "153\n",
      "157\n",
      "131\n",
      "207\n",
      "219\n",
      "163\n",
      "169\n",
      "151\n",
      "151\n",
      "175\n",
      "131\n",
      "115\n",
      "121\n",
      "121\n",
      "133\n",
      "133\n",
      "137\n",
      "181\n",
      "175\n",
      "181\n",
      "181\n",
      "245\n",
      "121\n",
      "149\n",
      "165\n",
      "161\n",
      "153\n",
      "149\n",
      "179\n",
      "177\n",
      "183\n",
      "189\n",
      "197\n",
      "197\n",
      "177\n",
      "169\n",
      "157\n",
      "185\n",
      "145\n",
      "143\n",
      "141\n",
      "139\n",
      "135\n",
      "235\n",
      "135\n",
      "135\n",
      "137\n",
      "67\n",
      "73\n",
      "133\n",
      "143\n",
      "171\n",
      "159\n",
      "155\n",
      "179\n",
      "181\n",
      "153\n",
      "173\n",
      "165\n",
      "173\n",
      "169\n",
      "173\n",
      "167\n",
      "163\n",
      "165\n",
      "159\n",
      "157\n",
      "153\n",
      "149\n",
      "155\n",
      "151\n",
      "157\n",
      "131\n",
      "157\n",
      "189\n",
      "189\n",
      "197\n",
      "181\n",
      "177\n",
      "197\n",
      "173\n",
      "147\n",
      "143\n",
      "117\n",
      "97\n",
      "59\n",
      "71\n",
      "41\n",
      "49\n",
      "61\n",
      "71\n",
      "73\n",
      "67\n",
      "65\n",
      "89\n",
      "171\n",
      "169\n",
      "155\n",
      "151\n",
      "225\n",
      "231\n",
      "221\n",
      "235\n",
      "235\n",
      "251\n",
      "261\n",
      "249\n",
      "225\n",
      "209\n",
      "207\n",
      "199\n",
      "209\n",
      "203\n",
      "193\n",
      "171\n",
      "167\n",
      "165\n",
      "159\n",
      "145\n",
      "137\n",
      "223\n",
      "121\n",
      "125\n",
      "111\n",
      "65\n",
      "71\n",
      "71\n",
      "55\n",
      "65\n",
      "81\n",
      "91\n",
      "93\n",
      "141\n",
      "81\n",
      "75\n",
      "85\n",
      "89\n",
      "265\n",
      "277\n",
      "285\n",
      "277\n",
      "243\n",
      "225\n",
      "203\n",
      "203\n",
      "221\n",
      "237\n",
      "233\n",
      "215\n",
      "207\n",
      "211\n",
      "195\n",
      "183\n",
      "163\n",
      "147\n",
      "161\n",
      "147\n",
      "149\n",
      "99\n",
      "123\n",
      "109\n",
      "111\n",
      "109\n",
      "109\n",
      "79\n",
      "79\n",
      "75\n",
      "83\n",
      "77\n",
      "79\n",
      "59\n",
      "75\n",
      "89\n",
      "269\n",
      "275\n",
      "277\n",
      "269\n",
      "239\n",
      "197\n",
      "179\n",
      "181\n",
      "193\n",
      "223\n",
      "229\n",
      "223\n",
      "215\n",
      "211\n",
      "213\n",
      "227\n",
      "199\n",
      "199\n",
      "179\n",
      "161\n",
      "137\n",
      "129\n",
      "109\n",
      "55\n",
      "9\n",
      "3\n",
      "3\n",
      "15\n",
      "11\n",
      "3\n",
      "21\n",
      "37\n",
      "49\n",
      "77\n",
      "107\n",
      "99\n",
      "79\n",
      "97\n",
      "57\n",
      "71\n",
      "75\n",
      "83\n",
      "75\n",
      "93\n",
      "267\n",
      "277\n",
      "271\n",
      "271\n",
      "281\n",
      "283\n",
      "279\n",
      "261\n",
      "257\n",
      "251\n",
      "229\n",
      "231\n",
      "251\n",
      "247\n",
      "247\n",
      "241\n",
      "229\n",
      "203\n",
      "193\n",
      "181\n",
      "169\n",
      "153\n",
      "149\n",
      "139\n",
      "121\n",
      "55\n",
      "49\n",
      "41\n",
      "41\n",
      "49\n",
      "59\n",
      "49\n",
      "61\n",
      "63\n",
      "71\n",
      "81\n",
      "85\n",
      "93\n",
      "105\n",
      "273\n",
      "287\n",
      "297\n",
      "285\n",
      "293\n",
      "265\n",
      "263\n",
      "233\n",
      "235\n",
      "243\n",
      "255\n",
      "275\n",
      "263\n",
      "235\n",
      "219\n",
      "195\n",
      "181\n",
      "161\n",
      "3\n",
      "33\n",
      "33\n",
      "37\n",
      "35\n",
      "41\n",
      "39\n",
      "59\n",
      "57\n",
      "71\n",
      "97\n",
      "101\n",
      "121\n",
      "123\n",
      "115\n",
      "101\n",
      "71\n",
      "87\n",
      "109\n",
      "99\n",
      "85\n",
      "63\n",
      "71\n",
      "79\n",
      "91\n",
      "101\n",
      "211\n",
      "207\n",
      "185\n",
      "71\n",
      "69\n",
      "67\n",
      "89\n",
      "139\n",
      "171\n",
      "179\n",
      "165\n",
      "59\n",
      "91\n",
      "115\n",
      "171\n",
      "227\n",
      "195\n",
      "189\n",
      "189\n",
      "163\n",
      "143\n",
      "127\n",
      "55\n",
      "99\n",
      "123\n",
      "97\n",
      "89\n",
      "77\n",
      "85\n",
      "73\n",
      "61\n",
      "59\n",
      "81\n",
      "87\n",
      "89\n",
      "151\n",
      "229\n",
      "199\n",
      "207\n",
      "203\n",
      "207\n",
      "189\n",
      "151\n",
      "143\n",
      "151\n",
      "135\n",
      "115\n",
      "79\n",
      "91\n",
      "89\n",
      "113\n",
      "123\n",
      "125\n",
      "153\n",
      "187\n",
      "187\n",
      "121\n",
      "155\n",
      "165\n",
      "181\n",
      "169\n",
      "175\n",
      "167\n",
      "201\n",
      "201\n",
      "195\n",
      "177\n",
      "171\n",
      "213\n",
      "219\n",
      "229\n",
      "195\n",
      "181\n",
      "189\n",
      "217\n",
      "193\n",
      "171\n",
      "153\n",
      "113\n",
      "89\n",
      "83\n",
      "61\n",
      "63\n",
      "59\n",
      "63\n",
      "105\n",
      "127\n",
      "167\n",
      "211\n",
      "99\n",
      "91\n",
      "97\n",
      "95\n",
      "89\n",
      "101\n",
      "155\n",
      "167\n",
      "189\n",
      "131\n",
      "111\n",
      "107\n",
      "87\n",
      "115\n",
      "129\n",
      "111\n",
      "99\n",
      "91\n",
      "141\n",
      "83\n",
      "81\n",
      "111\n",
      "111\n",
      "99\n",
      "121\n",
      "153\n",
      "165\n",
      "185\n",
      "209\n",
      "239\n",
      "253\n",
      "139\n",
      "137\n",
      "231\n",
      "207\n",
      "191\n",
      "199\n",
      "213\n",
      "209\n",
      "227\n",
      "233\n",
      "231\n",
      "223\n",
      "199\n",
      "179\n",
      "161\n",
      "159\n",
      "137\n",
      "169\n",
      "187\n",
      "219\n",
      "223\n",
      "229\n",
      "235\n",
      "239\n",
      "221\n",
      "177\n",
      "141\n",
      "127\n",
      "133\n",
      "111\n",
      "115\n",
      "105\n",
      "187\n",
      "229\n",
      "219\n",
      "207\n",
      "217\n",
      "231\n",
      "219\n",
      "175\n",
      "113\n",
      "43\n",
      "35\n",
      "125\n",
      "115\n",
      "115\n",
      "95\n",
      "107\n",
      "237\n",
      "231\n",
      "229\n",
      "221\n",
      "151\n"
     ]
    }
   ],
   "source": [
    "t = threading.Thread(target=Video_display)\n",
    "t.setDaemon(True)\n",
    "t.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid thread id",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[14], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;66;03m# 结束线程\u001b[39;00m\n\u001b[1;32m      2\u001b[0m clbrobot\u001b[38;5;241m.\u001b[39mt_stop(\u001b[38;5;241m0\u001b[39m) \u001b[38;5;66;03m# 停止电机\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mstop_thread\u001b[49m\u001b[43m(\u001b[49m\u001b[43mt\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[6], line 19\u001b[0m, in \u001b[0;36mstop_thread\u001b[0;34m(thread)\u001b[0m\n\u001b[1;32m     18\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mstop_thread\u001b[39m(thread):\n\u001b[0;32m---> 19\u001b[0m     \u001b[43m_async_raise\u001b[49m\u001b[43m(\u001b[49m\u001b[43mthread\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mident\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;167;43;01mSystemExit\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[6], line 13\u001b[0m, in \u001b[0;36m_async_raise\u001b[0;34m(tid, exctype)\u001b[0m\n\u001b[1;32m     11\u001b[0m res \u001b[38;5;241m=\u001b[39m ctypes\u001b[38;5;241m.\u001b[39mpythonapi\u001b[38;5;241m.\u001b[39mPyThreadState_SetAsyncExc(tid, ctypes\u001b[38;5;241m.\u001b[39mpy_object(exctype))\n\u001b[1;32m     12\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m res \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m---> 13\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minvalid thread id\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m     14\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m res \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m     15\u001b[0m     ctypes\u001b[38;5;241m.\u001b[39mpythonapi\u001b[38;5;241m.\u001b[39mPyThreadState_SetAsyncExc(tid, \u001b[38;5;28;01mNone\u001b[39;00m)\n",
      "\u001b[0;31mValueError\u001b[0m: invalid thread id"
     ]
    }
   ],
   "source": [
    "# 结束线程\n",
    "clbrobot.t_stop(0) # 停止电机\n",
    "stop_thread(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
